import {
  MDControlController,
  ICalendarEvent,
  ICalendarController,
  ICalendarState,
  MDCtrlLoadParams,
  ICalendarItemData,
} from '@ibiz-template/runtime';
import { ISysCalendar } from '@ibiz/model-core';
import dayjs from 'dayjs';
import { CalendarService } from './calendar.service';

/**
 * 日历部件控制器
 *
 * @author zk
 * @date 2023-08-09 11:08:46
 * @export
 * @class CalendarController
 * @extends {MDControlController<ISysCalendar, ICalendarState, ICalendarEvent>}
 * @implements {ICalendarController}
 */
export class CalendarController
  extends MDControlController<ISysCalendar, ICalendarState, ICalendarEvent>
  implements ICalendarController
{
  /**
   * 多数据部件服务
   *
   * @author zk
   * @date 2023-08-08 01:08:56
   * @type {CalendarService}
   * @memberof CalendarController
   */
  declare service: CalendarService;

  /**
   * 初始化状态
   *
   * @author zk
   * @date 2023-08-09 11:08:05
   * @protected
   * @memberof CalendarController
   */
  protected initState(): void {
    super.initState();
    this.state.selectedDate = new Date();
    this.state.size = 1000;
  }

  /**
   * 生命周期-创建完成
   *
   * @author zk
   * @date 2023-08-09 11:08:13
   * @protected
   * @return {*}  {Promise<void>}
   * @memberof CalendarController
   */
  protected async onCreated(): Promise<void> {
    await super.onCreated();
    this.service = new CalendarService(this.model);
    await this.service.init(this.context);
  }

  /**
   * 日历加载
   *
   * @author zk
   * @date 2023-08-08 01:08:24
   * @param {MDCtrlLoadParams} [args={}]
   * @return {*}  {Promise<IData[][]>}
   * @memberof CalendarController
   */
  async load(args: MDCtrlLoadParams = {}): Promise<ICalendarItemData[]> {
    const isInitialLoad = args.isInitialLoad === true;
    // *查询参数处理
    const { context } = this.handlerAbilityParams(args);
    const params = await this.getFetchParams(args?.params);
    // *发起请求
    await this.startLoading();
    let items;
    try {
      items = await this.service.search(context, params);
    } finally {
      await this.endLoading();
    }
    await this.afterLoad(args, items);
    this.state.isLoaded = true;
    this.state.items = items;
    await this.evt.emit('onLoadSuccess', {
      isInitialLoad,
    });
    return items;
  }

  /**
   * 获取当前选中的日期
   *
   * @author zk
   * @date 2023-08-08 11:08:44
   * @protected
   * @param {IParams} param
   * @return {*}  {IData}
   * @memberof CalendarController
   */
  protected getCurSelectDate(param: IParams): IData {
    const { selectedDate } = this.state;
    const { start, end } = param;
    if (!start || !end) {
      // 获取当前月份的第一天
      const firstDayOfMonth = new Date(
        selectedDate.getFullYear(),
        selectedDate.getMonth(),
        1,
      );
      // 获取下个月的第一天，然后减去一天
      const lastDayOfMonth = new Date(
        selectedDate.getFullYear(),
        selectedDate.getMonth() + 1,
        1,
      );
      return {
        start: dayjs(firstDayOfMonth).format('YYYY-MM-DD HH:mm:ss'),
        end: dayjs(lastDayOfMonth).format('YYYY-MM-DD HH:mm:ss'),
      };
    }
    return { start, end };
  }

  /**
   * 获取请求参数
   *
   * @author zk
   * @date 2023-08-09 11:08:35
   * @param {IParams} [extraParams={}]
   * @return {*}  {Promise<IParams>}
   * @memberof CalendarController
   */
  async getFetchParams(extraParams: IParams = {}): Promise<IParams> {
    const { curPage, size, sortQuery, noSort } = this.state;
    const resultParams: IParams = {
      ...this.params,
    };

    // 排序条件
    if (!noSort && sortQuery) {
      resultParams.sort = sortQuery;
    }
    // *请求参数处理
    await this._evt.emit('onBeforeLoad', undefined);
    // 合并搜索条件参数，这些参数在onBeforeLoad监听里由外部填入
    Object.assign(resultParams, {
      ...this.state.searchParams,
    });
    // 有size才给page和size。size默认值给0就不传分页和大小
    if (size) {
      resultParams.page = curPage - 1;
      resultParams.size = size;
    }

    // 额外附加参数
    if (extraParams) {
      Object.assign(resultParams, extraParams);
    }
    const timeParam = this.getCurSelectDate(resultParams);
    Object.assign(resultParams, timeParam);
    return resultParams;
  }

  /**
   * 行单击事件
   *
   * @author zk
   * @date 2023-08-08 05:08:15
   * @param {ICalendarItemData} data
   * @return {*}  {Promise<void>}
   * @memberof CalendarController
   */
  async onRowClick(data: ICalendarItemData): Promise<void> {
    // 选中相关处理
    const { selectedData } = this.state;
    // 选中里没有则添加，有则删除
    const filterArr = selectedData.filter(
      item => item.deData.srfkey !== data.deData.srfkey,
    );
    if (filterArr.length === selectedData.length) {
      this.setSelection(
        this.state.singleSelect ? [data] : selectedData.concat([data]),
      );
    } else {
      this.setSelection(filterArr);
    }

    // 激活事件
    if (this.state.mdctrlActiveMode === 1) {
      await this.setActive(data);
    }
  }

  /**
   * 设置选中日期
   *
   * @author zk
   * @date 2023-08-08 11:08:08
   * @param {Date} date
   * @memberof CalendarController
   */
  setSelectDate(date: Date): void {
    this.state.selectedDate = date;
  }
}
